package com.bjx.flow.mmx.service.impl;

import cn.hutool.core.util.StrUtil;
import com.bjx.flow.mmx.bean.MmxNextNodeData;
import com.bjx.flow.mmx.constant.MmxApproveConstant;
import com.bjx.flow.mmx.constant.MmxInstanceConstant;
import com.bjx.flow.mmx.constant.MmxNodeConstant;
import com.bjx.flow.mmx.domain.entity.MmxFlowDefinitionEntity;
import com.bjx.flow.mmx.domain.entity.MmxFlowHistoryEntity;
import com.bjx.flow.mmx.domain.entity.MmxFlowInstanceEntity;
import com.bjx.flow.mmx.domain.entity.MmxFlowTaskEntity;
import com.bjx.flow.mmx.extension.MmxAbstractApprover;
import com.bjx.flow.mmx.service.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @desc: 流程运行实现类
 * @author: liushuai
 * @date: 2023/5/22 11:12
 */
@Service
public class MmxRuntimeServiceImpl implements MmxRuntimeService {
    @Resource
    private MmxFlowDefinitionService flowDefinitionService;

    @Resource
    private MmxFlowInstanceService flowInstanceService;
    @Resource
    private MmxFlowDataService flowDataService;
    @Resource
    private MmxFlowHistoryService flowHistoryService;
    @Resource
    private MmxAbstractApprover approverService;
    @Resource
    private MmxFlowTaskService flowTaskService;


    @Transactional(rollbackFor = Exception.class)
    @Override
    public MmxFlowInstanceEntity startFlowByDefinitionKey(String definitionKey, String businessId, Map<String, Object> variables, String instanceName, String createUser, String comment, String ext1, String ext2, String ext3) {
        //查询最新的流程定义
        MmxFlowDefinitionEntity flowDefinition = flowDefinitionService.selectFlowDefinitionByDefinitionKey(definitionKey);
        //获取流程数据
        String flowData = flowDefinition.getFlowData();
        //插入流程实例
        MmxFlowInstanceEntity instance = flowInstanceService.insertFlowInstance(MmxFlowInstanceEntity.builder()
                .definitionId(flowDefinition.getDefinitionId())
                .definitionKey(definitionKey)
                .instanceName(instanceName)
                .ext1(ext1)
                .ext2(ext2)
                .ext3(ext3)
                .version(1)
                .status(MmxInstanceConstant.STATUS_ING)
                .businessId(businessId)
                .createUser(createUser)
                .build());
        //获取流程任务节点
        MmxNextNodeData nextNodeData = flowDataService.taskFlow(flowData, null, variables);
        flowHistoryService.insertFlowHistory(MmxFlowHistoryEntity.builder()
                .approveType(MmxApproveConstant.APPROVE_TYPE_START)
                .assignee(createUser)
                .createTime(new Date())
                .nodeId(nextNodeData.getStartNodeId())
                .comment(StrUtil.isEmpty(comment) ? "发起流程审批" : comment)
                .nodeName("开始节点")
                .nodeType(MmxNodeConstant.START)
                .build());
        List<MmxFlowTaskEntity> tasks = new ArrayList<>();
//        for (NodeData nodeData : nextNodeData.getNodeDataList()) {
//            String branchId = StrUtil.uuid();
//            //判断只要是用户节点,则返回下一个节点审批人
//            if (NodeConstant.USER_TASK.equals(nodeData.getType())) {
//                List<String> approver = approverService.getApprover(nodeData, variables);
//                for (String assignee : approver) {
//                    tasks.add(FlowTaskEntity.builder()
//                            .branchId(branchId)
//                            .businessId(businessId)
//                            .instanceId(instance.getInstanceId())
//                            .assignee(assignee)
//                            .nodeId(nodeData.getId())
//                            .nodeName(nodeData.getProperties().getNodeName())
//                            .instanceName(instance.getInstanceName())
//                            .build());
//                }
//            }
//        }
        flowTaskService.insertFlowTaskBatch(tasks);
        return instance;
    }
}
